package lt.ntec.sudokusolver.eqengine;

import lt.ntec.sudokusolver.Result;
import lt.ntec.sudokusolver.Solvable;

public class Solver implements Solvable {

	@Override
	public Result solve(int[][] nums) {
		return null;
	}

	protected double[] LinearEquationsSolving(int nDim, double[] pfMatr,
			double[] pfVect) throws UnsolvableException {
		double fMaxElem;
		double fAcc;
		double[] pfSolution = new double[nDim];

		int i, j, k, m;

		for (k = 0; k < (nDim - 1); k++) // base row of matrix
		{
			// search of line with max element
			fMaxElem = Math.abs(pfMatr[k * nDim + k]);
			m = k;
			for (i = k + 1; i < nDim; i++) {
				if (fMaxElem < Math.abs(pfMatr[i * nDim + k])) {
					fMaxElem = pfMatr[i * nDim + k];
					m = i;
				}
			}

			if (m != k) {
				for (i = k; i < nDim; i++) {
					fAcc = pfMatr[k * nDim + i];
					pfMatr[k * nDim + i] = pfMatr[m * nDim + i];
					pfMatr[m * nDim + i] = fAcc;
				}
				fAcc = pfVect[k];
				pfVect[k] = pfVect[m];
				pfVect[m] = fAcc;
			}

			if (pfMatr[k * nDim + k] == 0)
				throw new UnsolvableException("Non solvable");

			// triangulation of matrix with coefficients
			for (j = (k + 1); j < nDim; j++) // current row of matrix
			{
				fAcc = -pfMatr[j * nDim + k] / pfMatr[k * nDim + k];
				for (i = k; i < nDim; i++) {
					pfMatr[j * nDim + i] = pfMatr[j * nDim + i] + fAcc
							* pfMatr[k * nDim + i];
				}
				pfVect[j] = pfVect[j] + fAcc * pfVect[k]; // free member
															// recalculation
			}
		}

		for (k = (nDim - 1); k >= 0; k--) {
			pfSolution[k] = pfVect[k];
			for (i = (k + 1); i < nDim; i++) {
				pfSolution[k] -= (pfMatr[k * nDim + i] * pfSolution[i]);
			}
			pfSolution[k] = pfSolution[k] / pfMatr[k * nDim + k];
		}

		return pfSolution;
	}

}
